package com.abl.common.security;

import com.abl.common.security.annotation.ResC;
import com.abl.common.security.annotation.ResM;
import com.abl.common.util.StringKit;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * 资源注解处理器
 */
@Configuration
public class ApiHandler implements ApplicationContextAware {
    private static ApplicationContext context = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApiHandler.context = applicationContext;
    }

    public static synchronized HashMap<String, ArrayList<HashMap<String, Object>>> scanApi() {
        ArrayList<HashMap<String, Object>> cList = new ArrayList<>();
        ArrayList<HashMap<String, Object>> mList = new ArrayList<>();

        for (Object bean : ApiHandler.context.getBeansWithAnnotation(ResC.class).values()) {
            Class<?> aClass = bean.getClass();

            ResC resC = AnnotationUtils.findAnnotation(aClass, ResC.class);
            RestController restController = AnnotationUtils.findAnnotation(aClass, RestController.class);
            RequestMapping controllerMapping = AnnotationUtils.findAnnotation(aClass, RequestMapping.class);
            if (resC == null || restController == null || controllerMapping == null) continue;

            //遍历所有 Controller
            for (String cPath : controllerMapping.value()) {
                //class
                HashMap<String, Object> moduleEntity = new HashMap<>();
                moduleEntity.put("name", resC.value());
                moduleEntity.put("parentName", resC.value());
                moduleEntity.put("path", cPath);
                cList.add(moduleEntity);

                //method
                Method[] declaredMethods = aClass.getDeclaredMethods();
                //遍历Method
                for (Method method : declaredMethods) {
                    PostMapping PostMapping = AnnotationUtils.findAnnotation(method, PostMapping.class);
                    ResM resMethod = AnnotationUtils.findAnnotation(method, ResM.class);
                    if (PostMapping == null || resMethod == null) continue;

                    //遍历所有资源
                    for (String methodValue : PostMapping.value()) {
                        String methodPath = cPath + methodValue;
                        HashMap<String, Object> resEntity = new HashMap<>();
                        resEntity.put("path", methodPath);
                        resEntity.put("name", resMethod.value());
                        resEntity.put("login", resMethod.login());
                        resEntity.put("module", resMethod.module());
                        resEntity.put("permission", resMethod.permission());
                        resEntity.put("reSubmit", resMethod.reSubmit());
                        resEntity.put("actionLog", resMethod.actionLog());
                        resEntity.put("saveLogRequest", resMethod.saveLogRequest());
                        resEntity.put("saveLogResponse", resMethod.saveLogResponse());
                        resEntity.put("parentName", resC.value());
                        resEntity.put("parentPath", cPath);

                        //
//                        Parameter[] parameters = method.getParameters();
//                        Class<?>[] parameterTypes = method.getParameterTypes();
//                        Class<?> returnType = method.getReturnType();
                        String packageName = aClass.getPackageName();

                        resEntity.put("method_name", method.getName());
                        resEntity.put("class_name", StringKit.subBefore(aClass.getName(), "$$"));
                        resEntity.put("package", packageName);
                        System.out.println();
                        //                        	varchar	64		False	False		方法名（不可修改，服务启动自动更新）
                        //                        	varchar	32		False	False		类名（不可修改，服务启动自动更新）
                        //	varchar	500		False	False		包名（不可修改，服务启动自动更新）
                        //                        	varchar	500		False	False		类路径（不可修改，服务启动自动更新）


                        mList.add(resEntity);
                    }
                }
            }
        }

        HashMap<String, ArrayList<HashMap<String, Object>>> scanRes = new HashMap<>();
        scanRes.put("cList", cList);
        scanRes.put("mList", mList);
        return scanRes;
    }


}
